package com.supermap.dialogs;

import com.supermap.Helper;
import com.supermap.analyst.spatialanalyst.InterpolationRBFParameter;
import com.supermap.analyst.spatialanalyst.Interpolator;
import com.supermap.analyst.spatialanalyst.SearchMode;
import com.supermap.data.Enum;
import com.supermap.data.*;
import com.supermap.dialogs.advance.CJDialog;
import com.supermap.mapping.Map;

import javax.swing.*;
import java.awt.*;

public class InterpolationRBFDialog extends CJDialog {
    private JComboBox<String> srcDatasourceCmb;
    private JComboBox<String> srcDatasetCmb;
    private JComboBox<String> fieldNameCmb;
    private JComboBox<SearchMode> searchModeCmb;
    private JTextField resolutionTxt;
    private JTextField scaleTxt;
    private JTextField expectedCountTxt;
    private JTextField smoothTxt;
    private JTextField tensionTxt;
    private JCheckBox isUsedBarrierDataCbx;
    private JComboBox<String> barrierDatasourceCmb;
    private JComboBox<String> barrierDatasetCmb;
    private JComboBox<String> retDatasourceCmb;
    private JTextField retDatasetTxt;

    private Workspace workspace;

    private ProcessBarDialog processBarDialog;

    public InterpolationRBFDialog(Frame owner, String title, boolean modal, Workspace workspace) {
        super(owner, title, modal, 300, 500, new Object[]{workspace});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        workspace = (Workspace) args[0];
    }

    @Override
    protected void initializeCore() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridBagLayout());
        add(centerPanel, BorderLayout.CENTER);

        JPanel srcDataPanel = new JPanel();
        srcDataPanel.setBorder(BorderFactory.createTitledBorder("源数据"));
        srcDataPanel.setLayout(new GridBagLayout());
        centerPanel.add(srcDataPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDataPanel.add(new JLabel("数据源:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasourceCmb = new JComboBox<>();
        srcDataPanel.add(srcDatasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDataPanel.add(new JLabel("数据集:"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasetCmb = new JComboBox<>();
        srcDataPanel.add(srcDatasetCmb, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel paramsPanel = new JPanel();
        paramsPanel.setBorder(BorderFactory.createTitledBorder("参数设置"));
        paramsPanel.setLayout(new GridBagLayout());
        centerPanel.add(paramsPanel, new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("插值字段:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        fieldNameCmb = new JComboBox<>();
        paramsPanel.add(fieldNameCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("插值模式:"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        searchModeCmb = new JComboBox<>();
        paramsPanel.add(searchModeCmb, new GridBagConstraints(1, 1, 2, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        searchModeCmb.removeAll();
        Enum[] searchModes = Enum.getEnums(SearchMode.class);
        for (Enum searchMode : searchModes) {
            searchModeCmb.addItem((SearchMode) searchMode);
        }
        searchModeCmb.setSelectedItem(SearchMode.KDTREE_FIXED_COUNT);

        paramsPanel.add(new JLabel("分辨率:"), new GridBagConstraints(0, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        resolutionTxt = new JTextField("96");
        paramsPanel.add(resolutionTxt, new GridBagConstraints(1, 2, 2, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("缩放系数:"), new GridBagConstraints(0, 3, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        scaleTxt = new JTextField("1");
        paramsPanel.add(scaleTxt, new GridBagConstraints(1, 3, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("期望点数:"), new GridBagConstraints(0, 4, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        expectedCountTxt = new JTextField("12");
        paramsPanel.add(expectedCountTxt, new GridBagConstraints(1, 4, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("光滑系数:"), new GridBagConstraints(0, 5, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        smoothTxt = new JTextField("0.1");
        paramsPanel.add(smoothTxt, new GridBagConstraints(1, 5, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("张力系数:"), new GridBagConstraints(0, 6, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        tensionTxt = new JTextField("40");
        paramsPanel.add(tensionTxt, new GridBagConstraints(1, 6, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        isUsedBarrierDataCbx = new JCheckBox("是否使用障碍数据", false);
        paramsPanel.add(isUsedBarrierDataCbx, new GridBagConstraints(0, 7, 2, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        isUsedBarrierDataCbx.addChangeListener(e -> {
            boolean selected = isUsedBarrierDataCbx.isSelected();
            barrierDatasourceCmb.setEnabled(selected);
            barrierDatasetCmb.setEnabled(selected);
        });

        paramsPanel.add(new JLabel("障碍数据源:"), new GridBagConstraints(0, 8, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        barrierDatasourceCmb = new JComboBox<>();
        paramsPanel.add(barrierDatasourceCmb, new GridBagConstraints(1, 8, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        paramsPanel.add(new JLabel("障碍数据集:"), new GridBagConstraints(0, 9, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        barrierDatasetCmb = new JComboBox<>();
        paramsPanel.add(barrierDatasetCmb, new GridBagConstraints(1, 9, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel retDataPanel = new JPanel();
        retDataPanel.setBorder(BorderFactory.createTitledBorder("结果数据"));
        retDataPanel.setLayout(new GridBagLayout());
        centerPanel.add(retDataPanel, new GridBagConstraints(0, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDataPanel.add(new JLabel("数据源:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDatasourceCmb = new JComboBox<>();
        retDataPanel.add(retDatasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDataPanel.add(new JLabel("数据集:"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDatasetTxt = new JTextField();
        retDataPanel.add(retDatasetTxt, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasourceCmb.removeAll();
        barrierDatasourceCmb.removeAll();
        retDatasourceCmb.removeAll();
        Datasources datasources = workspace.getDatasources();
        for (int i = 0; i < datasources.getCount(); i++) {
            Datasource datasource = datasources.get(i);
            String datasourceAlias = datasource.getAlias();
            srcDatasourceCmb.addItem(datasourceAlias);
            barrierDatasourceCmb.addItem(datasourceAlias);
            retDatasourceCmb.addItem(datasourceAlias);
        }
        srcDatasourceCmb.addItemListener(e -> {
            String alias = (String) e.getItem();
            Datasource datasource = datasources.get(alias);
            Datasets datasets = datasource.getDatasets();
            srcDatasetCmb.removeAll();
            for (int i = 0; i < datasets.getCount(); i++) {
                Dataset dataset = datasets.get(i);
                if (dataset.getType() == DatasetType.POINT) {
                    srcDatasetCmb.addItem(dataset.getName());
                }
            }
        });
        barrierDatasourceCmb.addItemListener(e -> {
            String alias = (String) e.getItem();
            Datasource datasource = datasources.get(alias);
            Datasets datasets = datasource.getDatasets();
            barrierDatasetCmb.removeAll();
            for (int i = 0; i < datasets.getCount(); i++) {
                Dataset dataset = datasets.get(i);
                if (dataset.getType() == DatasetType.LINE) {
                    barrierDatasetCmb.addItem(dataset.getName());
                }
            }
        });
        retDatasourceCmb.addItemListener(e -> {
            String alias = (String) e.getItem();
            Datasource datasource = datasources.get(alias);
            Datasets datasets = datasource.getDatasets();
            retDatasetTxt.setText(datasets.getAvailableDatasetName("result_interpolationRBF"));
        });
        Datasource srcDatasource = datasources.get((String) srcDatasourceCmb.getSelectedItem());
        Datasets srcDatasets = srcDatasource.getDatasets();
        srcDatasetCmb.removeAll();
        for (int i = 0; i < srcDatasets.getCount(); i++) {
            Dataset dataset = srcDatasets.get(i);
            if (dataset.getType() == DatasetType.POINT) {
                srcDatasetCmb.addItem(dataset.getName());
            }
        }
        srcDatasetCmb.addItemListener(e -> {
            Datasource datasource = workspace.getDatasources().get((String) srcDatasourceCmb.getSelectedItem());
            DatasetVector datasetVector = (DatasetVector) datasource.getDatasets().get((String) srcDatasetCmb.getSelectedItem());
            FieldInfos fieldInfos = datasetVector.getFieldInfos();
            fieldNameCmb.removeAll();
            for (int i = 0; i < fieldInfos.getCount(); i++) {
                FieldInfo fieldInfo = fieldInfos.get(i);
                fieldNameCmb.addItem(fieldInfo.getName());
            }
        });
        srcDatasetCmb.setSelectedIndex(0);
        DatasetVector datasetVector = (DatasetVector) srcDatasource.getDatasets().get((String) srcDatasetCmb.getSelectedItem());
        FieldInfos fieldInfos = datasetVector.getFieldInfos();
        fieldNameCmb.removeAll();
        for (int i = 0; i < fieldInfos.getCount(); i++) {
            FieldInfo fieldInfo = fieldInfos.get(i);
            fieldNameCmb.addItem(fieldInfo.getName());
        }
        Datasource barrierDatasource = datasources.get((String) barrierDatasourceCmb.getSelectedItem());
        Datasets barrierDatasets = barrierDatasource.getDatasets();
        barrierDatasetCmb.removeAll();
        for (int i = 0; i < barrierDatasets.getCount(); i++) {
            Dataset dataset = barrierDatasets.get(i);
            if (dataset.getType() == DatasetType.LINE) {
                barrierDatasetCmb.addItem(dataset.getName());
            }
        }
        Datasource retDatasource = datasources.get((String) retDatasourceCmb.getSelectedItem());
        Datasets retDatasets = retDatasource.getDatasets();
        retDatasetTxt.setText(retDatasets.getAvailableDatasetName("result_interpolationRBF"));

        boolean selected = isUsedBarrierDataCbx.isSelected();
        barrierDatasourceCmb.setEnabled(selected);
        barrierDatasetCmb.setEnabled(selected);
    }

    @Override
    protected void doConfirmCore() {
        if (processBarDialog == null) {
            processBarDialog = new ProcessBarDialog((Frame) getOwner(), "样条插值", true);
            processBarDialog.setValue(0);
        }

        //返回用来进行插值分析的点数据集
        Datasources datasources = workspace.getDatasources();
        Datasource srcDatasource = datasources.get((String) srcDatasourceCmb.getSelectedItem());
        DatasetVector datasetElevPoints = (DatasetVector) srcDatasource.getDatasets().get((String) srcDatasetCmb.getSelectedItem());
        Datasource barrierDatasource = datasources.get((String) barrierDatasourceCmb.getSelectedItem());
        DatasetVector barrierDatasetVector = (DatasetVector) barrierDatasource.getDatasets().get((String) barrierDatasetCmb.getSelectedItem());
        Datasource retDatasource = datasources.get((String) retDatasourceCmb.getSelectedItem());
        String retDatasetName = retDatasetTxt.getText();

        String filedName = (String) fieldNameCmb.getSelectedItem();
        double scale = Double.parseDouble(scaleTxt.getText());

        InterpolationRBFParameter interpolationMethodRBFParam = new InterpolationRBFParameter();
        interpolationMethodRBFParam.setBounds(datasetElevPoints.getBounds());
        interpolationMethodRBFParam.setResolution(Double.parseDouble(resolutionTxt.getText()));
        interpolationMethodRBFParam.setTension(Double.parseDouble(tensionTxt.getText()));
        interpolationMethodRBFParam.setSmooth(Double.parseDouble(smoothTxt.getText()));
        interpolationMethodRBFParam.setSearchMode((SearchMode) searchModeCmb.getSelectedItem());

        if (isUsedBarrierDataCbx.isSelected()) {
            interpolationMethodRBFParam.setExpectedCount(Integer.parseInt(expectedCountTxt.getText()));
            interpolationMethodRBFParam.setBarrierDataset(barrierDatasetVector);
        }

        new Thread(() -> Interpolator.interpolate(interpolationMethodRBFParam, datasetElevPoints, filedName, scale, retDatasource, retDatasetName, PixelFormat.SINGLE, steppedEvent -> {
            int percent = steppedEvent.getPercent();
            processBarDialog.setValue(percent);
            if (percent == 100) {
                processBarDialog.setVisible(false);
            }
        })).start();

        processBarDialog.setVisible(true);
        setVisible(false);
    }
}
